<template>
  <el-card class="box-card">
    <el-form ref="form" label-width="80px" :rules="rules" :model="spu">
      <el-form-item label="SPU名称" prop="spuName">
        <el-input v-model="spu.spuName" placeholder="请输入SPU名称" />
      </el-form-item>

      <el-form-item label="SPU品牌" prop="tmId">
        <el-select v-model="spu.tmId" placeholder="请选择SPU品牌">
          <el-option
            v-for="tm in trademarkList"
            :key="tm.id"
            :label="tm.tmName"
            :value="tm.id"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述" prop="description">
        <el-input
          v-model="spu.description"
          type="textarea"
          placeholder="请输入SPU描述"
        />
      </el-form-item>

      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          accept="image/*"
          :limit="limit"
          :action="`${baseURL}/admin/product/fileUpload`"
          list-type="picture-card"
          :file-list="formatImageList"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
          :class="{ 'upload-show': spu.spuImageList.length === limit }"
        >
          <i class="el-icon-plus"></i>
          <div slot="tip" class="el-upload__tip">
            只能上传jpg/png文件，且不超过500kb
          </div>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible" width="440px">
          <img width="400px" :src="dialogImageUrl" alt="" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <div class="save-spu-saleAttr">
          <el-select
            v-model="spu.baseSaleAttr"
            :placeholder="`还剩${filterBaseSaleAttrList.length}个销售属性`"
          >
            <el-option
              v-for="attr in filterBaseSaleAttrList"
              :key="attr.id"
              :label="attr.name"
              :value="attr.name"
            />
          </el-select>
          <el-button
            type="primary"
            icon="el-icon-plus"
            :disabled="!spu.baseSaleAttr"
            @click="addSaleAttr"
          >
            添加销售属性值
          </el-button>
        </div>
        <el-table :data="spu.spuSaleAttrList" border style="width: 100%">
          <el-table-column
            type="index"
            align="center"
            label="序号"
            width="50"
          />
          <el-table-column prop="saleAttrName" label="属性名" width="100" />

          <el-table-column label="属性值列表">
            <template v-slot="{ row, $index }">
              <el-tag
                v-for="(attrValue, index) in row.spuSaleAttrValueList"
                :key="index"
                closable
                class="save-spu-tag"
                @close="handleClose(index, row)"
              >
                {{ attrValue.saleAttrValueName }}
              </el-tag>

              <el-input
                v-if="row.isEdit"
                :ref="$index"
                v-model.trim="spu.saleAttrValueName"
                placeholder="请输入属性值名称"
                size="mini"
                class="save-spu-input"
                @blur="addAttrValue(row, $index)"
              />
              <el-button
                v-else
                icon="el-icon-plus"
                @click="showInput(row, $index)"
              >
                添加属性值
              </el-button>
            </template>
          </el-table-column>

          <el-table-column label="操作" width="100">
            <template v-slot="{ $index }">
              <el-tooltip
                effect="dark"
                content="删除销售属性"
                placement="top-start"
              >
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="spu.spuSaleAttrList.splice($index, 1)"
                />
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="submitForm">确认</el-button>
        <el-button @click="$emit('setIsShow', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script>
import { reqGetTrademarkList } from '@/api/product/trademark'
import {
  reqGetBaseSaleAttrList,
  reqSaveSpuInfo,
  reqGetSpuImageList,
  reqGetSpuSaleAttrList,
  reqUpdateSpuInfo
} from '@/api/product/spu'
import { mapState } from 'vuex'
export default {
  name: 'SaveSpu',
  props: {
    currentSpu: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    // 自定义验证规则
    const validator = (rule, value, callback) => {
      // value:spu.spuSaleAttrList
      // SaleAttrList:每一行的数据
      // 必须要有一个属性名
      // 每个属性名必须要有一个属性值
      if (!value.length) {
        callback('请至少添加一个销售属性')
        return
      }
      if (
        !value.every(
          SaleAttrList => SaleAttrList.spuSaleAttrValueList.length > 0
        )
      ) {
        callback('每个销售属性至少添加一个销售属性值')
        return
      }
      callback()
    }
    return {
      // 请求地址前缀
      baseURL: process.env.VUE_APP_BASE_API,
      dialogVisible: false,
      dialogImageUrl: '',
      // spu品牌列表
      trademarkList: [],
      // 销售属性列表
      saleAttrList: [],
      // 表单收集的数据
      spu: {
        // 添加的销售属性值
        saleAttrValueName: '',
        // 选中的销售属性
        baseSaleAttr: '',
        // spu名称
        spuName: '',
        // spu品牌
        tmId: '',
        // spu描述
        description: '',
        // spu图片
        spuImageList: [],
        // 销售属性
        spuSaleAttrList: [],
        ...this.currentSpu
      },
      rules: {
        // spu名称
        spuName: [
          { required: true, message: '请输入spu名称', trigger: 'blur' }
        ],
        // spu品牌
        tmId: [{ required: true, message: '请选择spu品牌' }],
        // 描述
        description: [
          { required: true, message: '请输入spu描述', trigger: 'blur' }
        ],
        // spu图片
        spuImageList: [{ required: true, message: '请上传spu图片' }],
        // 销售属性
        spuSaleAttrList: [{ required: true, validator }]
      },
      // 限制图片上传数量
      limit: 3
    }
  },
  computed: {
    ...mapState('category', ['category3Id']),
    filterBaseSaleAttrList() {
      /*
      saleAttrList:销售属性列表,请求得来,是完整版的
      spu.spuSaleAttrList:表格中的销售属性
      逻辑:定义一个计算属性,对完整版的销售属性进行过滤,
      过滤条件为:在表格的销售属性中查找是否有和完整版同名的销售属性,有的话,就过滤掉
      */

      return this.saleAttrList.filter(attrList => {
        return !this.spu.spuSaleAttrList.find(
          saleAttr => saleAttr.saleAttrName === attrList.name
        )
      })
    },
    formatImageList() {
      return this.spu.spuImageList.map(img => {
        return {
          name: img.imgName,
          url: img.imgUrl,
          uid: img.uid || img.id
        }
      })
    }
  },
  async mounted() {
    // 发送多个请求,由于await的原因,会排队发,用promise.all来同步发送

    try {
      const { id } = this.spu
      let promises = [reqGetTrademarkList(), reqGetBaseSaleAttrList()]
      // 如果有id,就多加两个
      if (id) {
        promises = promises.concat([
          reqGetSpuImageList(id),
          reqGetSpuSaleAttrList(id)
        ])
      }

      const [
        trademarkListRes,
        saleAttrListRes,
        spuImageListRes,
        spuSaleAttrListRes
      ] = await Promise.all(promises)

      this.trademarkList = trademarkListRes.data
      this.saleAttrList = saleAttrListRes.data

      // 判断是否有值,有再添加
      if (spuImageListRes) {
        this.spu.spuImageList = spuImageListRes.data
        this.spu.spuSaleAttrList = spuSaleAttrListRes.data
      }
    } catch (e) {
      this.$message({
        type: 'error',
        message: '哎呀,数据走丢啦~'
      })
    }
  },
  methods: {
    // 提交表单
    submitForm() {
      // 对表单进行验证
      this.$refs.form.validate(async valid => {
        // 表单验证通过
        if (valid) {
          const { category3Id } = this
          const {
            description,
            spuImageList,
            spuName,
            spuSaleAttrList,
            tmId,
            id
          } = this.spu

          const data = {
            category3Id,
            description,
            spuImageList,
            spuName,
            spuSaleAttrList,
            tmId
          }

          // 有id是更新,无id是添加
          if (id) {
            await reqUpdateSpuInfo({ ...data, id })
          } else {
            await reqSaveSpuInfo(data)
          }

          this.$message({
            type: 'success',
            message: `${id ? '修改' : '添加'}spu成功`
          })
          // 切换回spuList组件
          this.$emit('setIsShow', 1)
        }
      })
    },
    // 关闭tag
    handleClose(index, row) {
      row.spuSaleAttrValueList.splice(index, 1)
    },
    // 失去焦点添加销售属性值
    addAttrValue(row, index) {
      row.isEdit = false
      const { saleAttrValueName } = this.spu
      // 有值的时候再添加
      if (saleAttrValueName) {
        row.spuSaleAttrValueList.push({
          saleAttrValueName,
          baseSaleAttrId: row.baseSaleAttrId
        })
      }
      // 添加成功后清掉输入框的值
      this.spu.saleAttrValueName = ''
    },
    // input框切换显示隐藏
    showInput(row, index) {
      this.$set(row, 'isEdit', true)
      this.$nextTick(() => {
        this.$refs[index].focus()
      })
    },
    // 点击添加销售属性
    addSaleAttr() {
      // 获取baseSaleAttrId-->在select中的那个属性的id
      const baseSaleAttrId = this.saleAttrList.find(
        saleAttr => saleAttr.name === this.spu.baseSaleAttr
      ).id
      // 把select中的数据push到表格中去
      this.spu.spuSaleAttrList.push({
        // 销售属性名
        saleAttrName: this.spu.baseSaleAttr,
        // 销售属性列表
        spuSaleAttrValueList: [],
        // id
        baseSaleAttrId,
        isEdit: false
      })
      // 添加成功后清空select选中的值
      this.spu.baseSaleAttr = ''
    },
    // 文件删除
    handleRemove(file) {
      console.log(file)
      const url = file.response ? file.response.data : file.url
      // 删掉本地的数据
      this.spu.spuImageList = this.spu.spuImageList.filter(
        img => img.imgUrl !== url
      )
    },
    // 文件预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // 文件上传成功后的回调
    handleAvatarSuccess(res, file) {
      // 上传成功后,更新页面的数据,才会在页面中显示
      // 数据中的属性按照服务器需求的数据来定
      this.spu.spuImageList.push({
        imgName: file.name,
        imgUrl: res.data,
        uid: file.uid
      })
      // 文件没有使用v-model,不能实时改变校验结果,上传成功后,清除logoUrl的校验
      this.$refs.form.clearValidate(['spuImageList'])
    },
    // 文件上传前的回调
    beforeAvatarUpload(file) {
      // 文件校验
      const imgType = ['image/jpeg', 'image/jpg', 'image/png']
      const isJPG = imgType.includes(file.type)
      const isLt500k = file.size / 1024 < 500

      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG 格式!')
      }
      if (!isLt500k) {
        this.$message.error('上传头像图片大小不能超过 500kb!')
      }
      return isJPG && isLt500k
    }
  }
}
</script>

<style lang="scss" scoped>
.save-spu-input {
  width: 150px;
}
.save-spu-tag {
  margin-right: 10px;
}
.save-spu-saleAttr {
  margin-bottom: 20px;
}
</style>
